from pickletools import uint8

import numpy
from PIL import ImageGrab
import numpy as np
import serial
import time
import serial.tools.list_ports

# 列出可用的串口供用户选择
ports = serial.tools.list_ports.comports()
for port in ports:
    print(f"{port.device}: {port.description}")

# 让用户输入要使用的串口名称
port_name = "COM4"
    # (input("请输入要使用的串口名称（如COM3或/dev/ttyUSB0）: "))

# 配置串口参数
baud_rate = 115200  # 波特率
timeout = 0.0001  # 读超时（秒）
count = 0
try:
    # 打开串口
    ser = serial.Serial(port_name, baud_rate, timeout=timeout)
    print(f"已打开串口: {port_name}")

    while 1:
        # 捕获整个屏幕
        screenshot = ImageGrab.grab()
        # 将图像转换为NumPy数组
        pixel_matrix = np.array(screenshot)
        # 打印像素矩阵的维度（可选）
        # print(pixel_matrix.shape)
        # 访问特定位置的像素（例如，获取(x, y)位置的像素值）
        x, y = 100, 200
        pixel_value = pixel_matrix[y, x]  # 注意：PIL图像是(高, 宽)格式，NumPy数组是(行, 列)格式
        # print(pixel_value)
        # 计算对应数据灰度
        grey = 0.299 * pixel_matrix[:, :, 0] + 0.587 * pixel_matrix[:, :, 1] + 0.114 * pixel_matrix[:, :, 2]
        # 将对应数据映射到高64宽128的空间中

        # 预先计算块的大小和屏幕数组的尺寸
        block_height = 16
        block_width = 15
        screen_height = 64
        screen_width = 128

        # 创建一个用于存储结果的布尔数组
        screen = np.zeros((screen_height, screen_width), dtype=bool)
        # 使用切片和矢量化操作来计算平均灰度值
        # 注意：这里我们假设grey的尺寸足够大，以包含所有必要的像素
        # 如果不是，您可能需要添加适当的边界检查或填充
        for i in range(screen_height):
            for j in range(screen_width):
                # 通过5点取样法来减少单个单元的算力消耗
                average_value = 0
                average_value += grey[i * 16 + 8, j * 15 +7]
                # 计算平均灰度值
                # 应用阈值来设置screen数组的值
                if average_value > 128:
                    screen[i, j] = True

        # 创建一个新的大小为128x8的字节数组
        byte_array = bytearray(1026)
        num = 1
        for i in range(8):
            for j in range(128):
                mybyte = 0
                power = 1
                for index in range(8):
                    mybyte += screen[i*8+index,j] * power
                    power <<= 1
                byte_array[num] = mybyte
                num += 1

        byte_array[0] = 0XAA
        byte_array[1025] = 0XBB

        # 发送数据
        ser.write(byte_array)
        count+=1
        time.sleep(0.08)
        if count>=50:
            break

    # 关闭串口
    ser.close()
    print("已关闭串口")

except serial.SerialException as e:
    print(f"串口错误: {e}")
